#include <iostream>
#include <stdexcept>

template <typename T>
class MyStack {
private:
    // 链表节点定义
    struct Node {
        T data;
        Node* next;
        Node(const T& data) : data(data), next(NULL) {}
    };

    Node* topNode;  // 栈顶指针
    size_t count;   // 元素计数

public:
    // 构造函数
    MyStack() : topNode(NULL), count(0) {}

    // 析构函数
    ~MyStack() {
        clear();
    }

    // 拷贝构造函数
    MyStack(const MyStack& other) : topNode(NULL), count(0) {
        // 使用临时栈保持元素顺序
        MyStack temp;
        Node* current = other.topNode;
        while (current != NULL) {
            temp.push(current->data);
            current = current->next;
        }
        
        // 将元素从临时栈弹出，恢复到当前栈中
        while (!temp.isEmpty()) {
            push(temp.pop());
        }
    }

    // 赋值运算符
    MyStack& operator=(const MyStack& other) {
        if (this != &other) {
            clear();
            MyStack temp(other);
            std::swap(topNode, temp.topNode);
            std::swap(count, temp.count);
        }
        return *this;
    }

    // 入栈操作
    void push(const T& item) {
        Node* newNode = new Node(item);
        newNode->next = topNode;
        topNode = newNode;
        count++;
    }

    // 出栈操作
    T pop() {
        if (isEmpty()) {
            throw std::underflow_error("栈为空，无法出栈");
        }
        T item = topNode->data;
        Node* temp = topNode;
        topNode = topNode->next;
        delete temp;
        count--;
        return item;
    }

    // 查看栈顶元素（不删除）
    T peek() const {
        if (isEmpty()) {
            throw std::underflow_error("栈为空，无法查看栈顶元素");
        }
        return topNode->data;
    }

    // 检查栈是否为空
    bool isEmpty() const {
        return count == 0;
    }

    // 获取栈当前元素数量
    size_t size() const {
        return count;
    }

    // 清空栈
    void clear() {
        while (!isEmpty()) {
            pop();
        }
    }
};

// 测试代码
int main() {
    MyStack<int> stack;  // 创建一个整型栈

    // 测试入栈
    stack.push(10);
    stack.push(20);
    stack.push(30);
    std::cout << "栈顶元素: " << stack.peek() << std::endl;
    std::cout << "栈大小: " << stack.size() << std::endl;

    // 测试出栈
    std::cout << "出栈元素: " << stack.pop() << std::endl;
    std::cout << "出栈后栈顶元素: " << stack.peek() << std::endl;

    // 测试拷贝构造
    MyStack<int> stack2 = stack;
    std::cout << "拷贝构造后的栈大小: " << stack2.size() << std::endl;

    // 测试赋值运算符
    MyStack<int> stack3;
    stack3 = stack;
    std::cout << "赋值后的栈大小: " << stack3.size() << std::endl;

    // 测试清空栈
    stack.clear();
    std::cout << "清空后栈大小: " << stack.size() << std::endl;

    return 0;
}